package id.co.rho.scoring.cid.server.service.impl;

import id.co.rho.scoring.cid.client.command.impl.LoginCommandResult;
import id.co.rho.scoring.cid.client.security.Credential;
import id.co.rho.scoring.cid.client.security.impl.RealCredential;
import id.co.rho.scoring.cid.domain.AppUser;
import id.co.rho.scoring.cid.domain.WebSession;
import id.co.rho.scoring.cid.server.dao.GenericDao;
import id.co.rho.scoring.cid.server.dao.LoginDao;
import id.co.rho.scoring.cid.server.service.LoginService;
import id.co.rho.scoring.cid.server.util.IdGenerator;
import id.co.rho.scoring.cid.server.util.MD5Hash;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Created by IntelliJ IDEA.
 * User: frizky
 * Date: 10/17/11
 * Time: 2:22 PM
 */

@Service
@Transactional
public class LoginServiceImpl implements LoginService {
	Logger log = Logger.getLogger(this.getClass().getName());
    GenericDao genericDao;
    LoginDao loginDao;

    @Autowired
    public void setGenericDao(GenericDao genericDao) {
        this.genericDao = genericDao;
    }

    @Autowired
    public void setLoginDao(LoginDao loginDao) {
        this.loginDao = loginDao;
    }

	@Override
    public LoginCommandResult validateLogin(String userId, String password) {
		LoginCommandResult loginCommandResult = new LoginCommandResult();
		Credential credential = queryUser(userId);
        if(credential!=null){

        	//Password Check
        	try {
				String hashPass = MD5Hash.hash1(password);
				if(!hashPass.equalsIgnoreCase(credential.getPassword())){
					loginCommandResult.setMessage("Password incorrect");
					return loginCommandResult;
				}
				if(!credential.getUserStatus().equalsIgnoreCase("1")){
					loginCommandResult.setMessage("User not active yet");
					return loginCommandResult;
				}
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
        	String stringCockie = generateId();
            WebSession session = new WebSession();
            session.setSessionId(stringCockie);
            session.setCreatedDate(new Date());
        	session.setUserId(credential.getId());
        	session.setCreatedBy(userId);
        	this.genericDao.saveOrUpdate(session);

        	loginCommandResult.setStringCockie(stringCockie);
            loginCommandResult.setCredential(credential);
        }else{
        	loginCommandResult.setMessage("user not registered");
        }

        return loginCommandResult;
    }

    @Override
    public LoginCommandResult validateSessionId(String stringCockie) {
        WebSession webSessionBySessionId = loginDao.findWebSessionBySessionId(stringCockie);
        LoginCommandResult loginCommandResult = new LoginCommandResult();
        if (webSessionBySessionId != null && webSessionBySessionId.getUserId() != null) {
            AppUser appUser = genericDao.find(AppUser.class, webSessionBySessionId.getUserId());

            Credential credential = queryUser(appUser.getUserId());

            loginCommandResult.setCredential(credential);
            Long id = credential.getId();

            if(credential==null){
            	loginCommandResult.setMessage("session not valid");
            }
        }
        return loginCommandResult;
    }

    @Override
    public LoginCommandResult logout(String stringCockie) {
    	LoginCommandResult result = new LoginCommandResult();
        WebSession webSessionBySessionId = loginDao.findWebSessionBySessionId(stringCockie);
        if(webSessionBySessionId!=null){
        	this.genericDao.remove(webSessionBySessionId);
        }
        return result;
    }

    public String generateId() {
        IdGenerator idGenerator = new IdGenerator();
        String s = idGenerator.generateId(16);
        if (loginDao.findWebSessionBySessionId(s) == null)
            return s;
        else return generateId();
    }

    public Credential queryUser(String userId){
    	String query = "from AppUser where userId = :userId and userId.deletedFlag <> true";
        Map parameters = new HashMap();
        parameters.put("userId", userId);
        List<AppUser> appUsers = genericDao.getList(query, false, parameters);

        RealCredential credential = null;
        if(appUsers!=null && appUsers.size()>0){
        	AppUser user = appUsers.get(0);
        	log.log(Level.INFO, "Login user: "+ user.getUserId());

        	credential = new RealCredential();
	        credential.setUserId(user.getUserId());
	        credential.setUsername(user.getUserName());
	        credential.setId(user.getId());
	        credential.setPassword(user.getUserPass());
	        credential.setUserStatus(user.getUserStatus());

    	}
        return credential;
    }
    
}

